#include <wifi_manager.h>
#include <PubSubClient.h>
#include <mqtt_manager.h>
#include <HaMqttEntities.h>
#include <config.h>
// mqtt客户端
PubSubClient client(wifiClient);

// Home Assistant
#define HA_ENTITIES_COUNT 3
char *HA_DEVICE_NAME = new char[32];
char *HA_DEVICE_VERSION = new char[16];
HASensorNumeric *ha_sensor_humidity;
HASensorNumeric *ha_sensor_temp_c;
HASwitch *ha_switch;
HADevice *ha_device;

// 全局变量或类成员，记录上次发送时间（毫秒）
unsigned long lastMqttConnectTime = 0;

// 状态控制，如果关了不上报数据
bool isSend = true;

bool isNeedMQTTReconnect = false;

void ha_callback(HAEntity *entity, char *topic, byte *payload, unsigned int length)
{
  if (entity == ha_switch)
  {
    isSend = ha_switch->getState();
    Serial.print("收到开关状态：");
    Serial.println(isSend);
    // 如果关闭了，一直红灯,开启了就关闭红灯
    if (!isSend)
    {
      rgbLedWrite(RGB_BUILTIN, RGB_BRIGHTNESS, 0, 0);
    }
    else
    {
      digitalWrite(RGB_BUILTIN, LOW);
    }
  }
}

void mqttInit()
{
  preferences.begin("mqtt", false);
  String mqttIp = preferences.getString("ip", "");
  int port = preferences.getInt("port", 1883);
  String clientId = preferences.getString("clientId", "");
  preferences.end();
  size_t len = mqttIp.length() + 1;
  char *ipChar = new char[len];
  strcpy(ipChar, mqttIp.c_str());
  // 初始化mqtt clinet 并 HA初始化
  client.setServer(ipChar, port);
  uint64_t mac = ESP.getEfuseMac();
  strcpy(HA_DEVICE_NAME, "foxchen");
  strcpy(HA_DEVICE_VERSION, "1.0.0");
  ha_device = new HADevice(clientId.c_str(), HA_DEVICE_NAME, HA_DEVICE_VERSION);
  ha_sensor_temp_c = new HASensorNumeric("temp_c", "温度(摄氏度)", *ha_device, "°C", 2);
  ha_sensor_humidity = new HASensorNumeric("humidity", "湿度", *ha_device, "%", 2);
  ha_switch = new HASwitch("switch", "数据是否上报", *ha_device);
  HAMQTT.begin(client, HA_ENTITIES_COUNT);
  HAMQTT.addEntity(*ha_sensor_humidity);
  HAMQTT.addEntity(*ha_sensor_temp_c);
  HAMQTT.addEntity(*ha_switch);
  HAMQTT.setCallback(ha_callback);

  // 连接mqtt，并且设置开关状态
  mqttCheck();

  // ha开关标记需要上报数据
  ha_switch->setState(true);
}

void mqttCheck()
{
  unsigned long now = millis();
  if ((now - lastMqttConnectTime < 2000) && !isNeedMQTTReconnect)
  {
    return;
  }

  if (!HAMQTT.connected() || isNeedMQTTReconnect)
  {
    // 如果是重新连接，已经触发了则标记不是重新连接了
    preferences.begin("mqtt", true);
    if (isNeedMQTTReconnect)
    {
      Serial.print("MQTT重新连接...");
      isNeedMQTTReconnect = false;
      String mqttIp = preferences.getString("ip", "");
      int port = preferences.getInt("port", 1883);
      Serial.println("连接 MQTT,IP:" + mqttIp);
      Serial.println("连接 MQTT,port:" + String(port));
      size_t len = mqttIp.length() + 1;
      char *ipChar = new char[len];
      strcpy(ipChar, mqttIp.c_str());
      client.setServer(ipChar, port);
      HAMQTT.begin(client, HA_ENTITIES_COUNT);
    }
    String clientId = preferences.getString("clientId", "");
    String username = preferences.getString("username", "");
    String password = preferences.getString("password", "");
    preferences.end();
    boolean mqttOK = HAMQTT.connect(clientId.c_str(), username.c_str(), password.c_str());
    if (!mqttOK)
    {
      Serial.println("MQTT连接失败...");
      lastMqttConnectTime = now;
    }
    else
    {
      Serial.println("HAMQTT连接成功");
    }
  }

  if (HAMQTT.connected())
  {
    HAMQTT.loop();
  }
}
